/*	MainFrame.java
 *
 *	Copyright (c) Manateem Challenge Group, Zaia Group, and contributors 2010
 *
 *	This file is part of MSGSwingSet ('this project').
 *	
 *	This project is free software: you can redistribute it and/or modify it
 *	under the terms of the GNU General Public License as published by the Free
 *	Software Foundation, either version 3 of the License, or (at your option)
 *	any later version.
 *	
 *	This project is distributed in the hope that it will be useful, but WITHOUT
 *	ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *	FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 *	more details.
 *	
 *	You should have received a copy of the GNU General Public License along with
 *	this project. If not, see <http://www.gnu.org/licenses/>.
 */
package edu.bu.manateem.msg.gui;

// Imports
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import edu.bu.manateem.msg.MSGConstants;
import edu.bu.manateem.msg.gui.view.ViewFrame;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *	<p>
 *	Application main hub. GUI component for global (per application) components.
 *	This includes global settings, main navigation, and environment handling,
 *	and application behaviors (e.g. close).
 *	</p>
 *
 *
 *	@author
 *		Christopher Jacobs
 *
 *	@version
 *		1.0
 *
 *	@changelog
 *		May 12, 2010	- Version 1.0.
 */
public class MainFrame
	extends JFrame
{
	/*
	 * TYPES
	 */

	/*
	 * CONSTANTS
	 */

	// Serialize
	private static final long serialVersionUID = 1L;
	// Logging
	private static final Logger LOG = LoggerFactory.getLogger(MainFrame.class);
	
	// Layout properties
	private static final int FRAME_DEFAULT_WIDTH =
		MSGConstants.SCREEN_SIZE.width / 2;
	private static final int FRAME_DEFAULT_HEIGHT = 75;
	private static final int FRAME_DEFAULT_OFFSET_X =
		MSGConstants.SCREEN_SIZE.width / 4;
	private static final int FRAME_DEFAULT_OFFSET_Y = 10;
	private static final Dimension FRAME_DEFAULT_SIZE =
		new Dimension(MainFrame.FRAME_DEFAULT_WIDTH,
			MainFrame.FRAME_DEFAULT_HEIGHT);
	private static final Point FRAME_DEFAULT_OFFSET =
		new Point(MainFrame.FRAME_DEFAULT_OFFSET_X,
			MainFrame.FRAME_DEFAULT_OFFSET_Y);
	
	// private static final int X_SPACE_BETWEEN_COMPONENTS = 10;
	// private static final int Y_SPACE_BETWEEN_COMPONENTS = 10;
	// private static final Dimension SPACE_BETWEEN_COMPONENTS =
	// new Dimension(MainFrame.X_SPACE_BETWEEN_COMPONENTS,
	// MainFrame.Y_SPACE_BETWEEN_COMPONENTS);
	//	
	// private static final int BORDER_SIZE_TOP = 15;
	// private static final int BORDER_SIZE_BOTTOM = 5;
	// private static final int BORDER_SIZE_LEFT = 10;
	// private static final int BORDER_SIZE_RIGHT = 10;
	
	/*
	 * FIELDS
	 */

	AboutDialog aboutDialog = new AboutDialog();
	
	/*
	 * CONSTRUCTORS
	 */

	/**
	 *	<p>
	 *	Basic constructor. Creates an instance of the main MSG application hub
	 *	window, using all application defaults.
	 *	</p>
	 *
	 *	@since
	 *		1.0
	 */
	public MainFrame()
	{
		super();
		
		MainFrame.LOG.debug("init self");
		MainFrame.LOG.info("heap size is " + Runtime.getRuntime().maxMemory()
			+ "MB");
		
		initMenu();
		init();
	}
	
	/*
	 * INITIALIZERS
	 */

	/*
	 * METHODS
	 */

	/**
	 *	<p>
	 *	Initializes <code>this</code> object. Sets the default frame behaviors
	 *	and layout, and packs components.
	 *	</p>
	 *
	 *	@since
	 *		1.0
	 */
	private void init()
	{
		MainFrame.LOG.debug("build container");
		
		// behavior
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setTitle("Manatee");
		
		// layout
		setLocation(MainFrame.FRAME_DEFAULT_OFFSET);
		setPreferredSize(MainFrame.FRAME_DEFAULT_SIZE);
		
		// finish
		pack();
		
		MainFrame.LOG.debug("build container -- DONE");
	}
	
	/**
	 *	<p>
	 *	Initializes the menu bar for <code>this</code> object. The menu bar is
	 *	used as the main navigatory tool for this application. The menu bar is
	 *	generated dynamically from constant gui instances.
	 *	</p>
	 *
	 *	@see
	 *		edu.bu.manateem.msg.gui.GUIConstants
	 *
	 *	@since
	 *		1.0
	 */
	private void initMenu()
	{
		// Analysis menu (items)
		MainFrame.LOG.debug("build analysis menu");
		JMenu analysisMenu = new JMenu("Analysis");
		analysisMenu.setMnemonic(KeyEvent.VK_A);
		MainFrame.LOG.debug("build analysis menu -- DONE");
		
		for (String analysisName : GUIConstants.ANALYSES_MAP.keySet())
		{
			MainFrame.LOG.debug("build menu item for {}",analysisName);
			JMenuItem analysisMenuItem = new JMenuItem(analysisName);
			analysisMenuItem.addActionListener(new ActionListener()
			{
				@Override
				public void actionPerformed(ActionEvent e)
				{
					// TODO
					try
					{
						MainFrame.LOG.info("start new {}...",
							e.getActionCommand());
						GUIConstants.ANALYSES_MAP.get(e.getActionCommand()).newInstance();
					}
					catch (InstantiationException x)
					{
						MainFrame.LOG.error("cannot instantiate {}",
							e.getActionCommand());
					}
					catch (IllegalAccessException x)
					{
						MainFrame.LOG.error("illegal access on {}",
							e.getActionCommand());
					}
				}
				
			});
			analysisMenuItem.setActionCommand(analysisName);
			analysisMenu.add(analysisMenuItem);
			MainFrame.LOG.debug("build menu item for {} -- DONE",analysisName);
		}
		
		// View menu (items)
		MainFrame.LOG.debug("build view menu");
		JMenu viewMenu = new JMenu("View");
		viewMenu.setMnemonic(KeyEvent.VK_V);
		MainFrame.LOG.debug("build view menu -- DONE");
		
		for (String viewName : GUIConstants.VIEW_MAP.keySet())
		{
			MainFrame.LOG.debug("build menu item for {}",viewName);
			JMenuItem viewMenuItem = new JMenuItem(viewName);
			viewMenuItem.addActionListener(new ActionListener()
			{
				@Override
				public void actionPerformed(ActionEvent e)
				{
					// TODO
					try
					{
						MainFrame.LOG.info("start new {}...",
							e.getActionCommand());
						ViewFrame frame =
							GUIConstants.VIEW_MAP.get(e.getActionCommand()).newInstance();
						if (frame.isEmptyView())
						{
							frame.disposeView();
						}
						
					}
					catch (InstantiationException x)
					{
						MainFrame.LOG.error("cannot instantiate {}",
							e.getActionCommand());
					}
					catch (IllegalAccessException x)
					{
						MainFrame.LOG.error("illegal access on {}",
							e.getActionCommand());
					}
				}
				
			});
			viewMenuItem.setActionCommand(viewName);
			viewMenu.add(viewMenuItem);
			MainFrame.LOG.debug("build menu item for {} -- DONE",viewName);
		}
		
		// Other menu items
		MainFrame.LOG.debug("build help menu");
		JMenu helpMenu = new JMenu("Help");
		helpMenu.setMnemonic(KeyEvent.VK_V);
		MainFrame.LOG.debug("build help menu -- DONE");
		
		JMenuItem helpItem = new JMenuItem("Help");
		helpMenu.add(helpItem);
		helpItem.setEnabled(false); // TODO remove when help is available
		
		JMenuItem aboutItem = new JMenuItem("About");
		aboutItem.addActionListener(new ActionListener()
		{
			
			@Override
			public void actionPerformed(ActionEvent e)
			{
				aboutDialog.setVisible(true);
			}
		});
		helpMenu.add(aboutItem);
		
		// Menu bar
		MainFrame.LOG.debug("build menu bar");
		JMenuBar menubar = new JMenuBar();
		menubar.add(analysisMenu);
		menubar.add(viewMenu);
		menubar.add(helpMenu);
		setJMenuBar(menubar);
		MainFrame.LOG.debug("build menu bar -- DONE");
	}
}
